package com.yuyh.library.nets;

import android.text.TextUtils;
import android.util.Log;

import com.yuyh.library.nets.converters.GsonConverterFactory;


import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.CallAdapter;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * created by arvin on 16/11/21 23:06
 * email：1035407623@qq.com
 */
public abstract class BaseNet<T> {

    private static final String TAG = "BaseNet";

    private T api;
    private T apiW;
    private T apiP;
    private T apiWP;
    private T apiPP;
    private Class<T> clazz;
    private OkHttpClient okHttpClient;
    private String token;
    private String deviceId;

    @SuppressWarnings("FieldCanBeLocal")
    private InputStream mCertificate;

    private Converter.Factory converterFactory;
    private CallAdapter.Factory rxJavaCallAdapterFactory;
    private Long timestamp;

    protected BaseNet() {
        converterFactory = GsonConverterFactory.create();
        rxJavaCallAdapterFactory = RxJava2CallAdapterFactory.create();
        clazz = getApiClazz();
    }

    public T getApi() {
        if (api == null) {
            initHttpClient();
            Retrofit retrofit = new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl(getBaseUrl())
                    .addConverterFactory(converterFactory)
                    .addCallAdapterFactory(rxJavaCallAdapterFactory)
                    .build();
            Log.i(TAG, "getApi: ----"+retrofit.toString());
            api = retrofit.create(clazz);
        }
        return api;
    }

    public T getApiW() {
//        Log.i("-----", "getApiW: "+getBaseUrlW());
        if (apiW == null) {
            initHttpClient();
            Retrofit retrofit = new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl(getBaseUrlW())
                    .addConverterFactory(converterFactory)
                    .addCallAdapterFactory(rxJavaCallAdapterFactory)
                    .build();
//            Log.i("-----", "getApiW010: "+ retrofit.toString());
            apiW = retrofit.create(clazz);
        } else {
//            Log.i("-----", "getApiW011: ");
        }
        return apiW;
    }

    public T getApiP() {
        if (apiP == null) {
            initHttpClient();
            Retrofit retrofit = new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl(getBaseUrlP())
                    .addConverterFactory(converterFactory)
                    .addCallAdapterFactory(rxJavaCallAdapterFactory)
                    .build();
            apiP = retrofit.create(clazz);
        } else {

        }
        return apiP;
    }

    public T getApiWP() {
        if (apiWP == null) {
            initHttpClient();
            Retrofit retrofit = new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl(getBaseUrlWP())
                    .addConverterFactory(converterFactory)
                    .addCallAdapterFactory(rxJavaCallAdapterFactory)
                    .build();
            apiWP = retrofit.create(clazz);
        } else {

        }
        return apiWP;
    }
    public T getApiPP() {
        if (apiPP == null) {
            initHttpClient();
            Retrofit retrofit = new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl(getBaseUrlPP())
                    .addConverterFactory(converterFactory)
                    .addCallAdapterFactory(rxJavaCallAdapterFactory)
                    .build();
            apiPP = retrofit.create(clazz);
        } else {

        }
        return apiPP;
    }

    private void initHttpClient() {
        if (okHttpClient == null) {

            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

            OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request;
                    timestamp=System.currentTimeMillis();
                    if (!TextUtils.isEmpty(token)) {
                        request = chain.request().newBuilder()
                                .addHeader("version", "1.0")
                                .addHeader("token", token)
                                .addHeader("timestamp",String.valueOf(timestamp))
                                .build();
                    } else {
                        request = chain.request().newBuilder()
                                .addHeader("version", "1.0")
                                .addHeader("timestamp",String.valueOf(timestamp))
                                .build();
                    }
                    Response response = chain.proceed(request);
                    dealResponse(response);
                    return response;
                }
            }).addInterceptor(loggingInterceptor);

            builder.retryOnConnectionFailure(true);
            builder.connectTimeout(300, TimeUnit.SECONDS);
            builder.writeTimeout(300, TimeUnit.SECONDS);
            builder.readTimeout(300, TimeUnit.SECONDS);

            okHttpClient = builder.build();
        }
    }

    protected void dealResponse(Response response) {
    }

    /**
     * 若需要使用https请求,请设置证书信息
     */
    private boolean isNeedHttps() {
        return false;
    }

    protected void setCertificateInputStream(InputStream certificate) {
        mCertificate = certificate;
    }

    public void setToken(String token) {
        this.token = token;
        clear();
    }

    public String getToken() {
        return token;
    }

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }

    public String getDeviceId() {
        return deviceId;
    }

    private void clear() {
        okHttpClient = null;
        api = null;
    }

    protected abstract Class<T> getApiClazz();

    protected abstract String getBaseUrl();

    protected abstract String getBaseUrlW();

    protected abstract String getBaseUrlP();

    protected abstract String getBaseUrlWP();

    protected abstract String getBaseUrlPP();

    protected Request dealRequest(Request request) {
        return request;
    }
}
